/**
 * Copyright (c) 2012-2014 All Rights Reserved.
 */
package com.easy.framwork.datasoruce;

import java.beans.PropertyVetoException;
import java.util.Map;

import javax.sql.DataSource;

import com.easy.framwork.exceptions.IllegalArgException;
import com.easy.framwork.utils.PropertiesUtils;
import com.easy.framwork.utils.StringUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * c3p0数据源
 * 
 * @author wy
 * @version v 0.1 2014-1-1 下午12:52:43 wy Exp $
 */
public class C3p0DatasourceProvider implements DatasourceProvider {

    private String jdbcUrl;
    private String user;
    private String password;
    private String driverClass = "com.mysql.jdbc.Driver";
    private int maxPoolSize = 100;
    private int minPoolSize = 10;
    private int initialPoolSize = 10;
    private int maxIdleTime = 20;
    private int acquireIncrement = 2;

    /** 数据源信息 */
    private ComboPooledDataSource dataSource;

    /**
     * 
     */
    public C3p0DatasourceProvider() {
        this("jdbc.properties");
    }

    public C3p0DatasourceProvider(String properties) {

        Map<String, String> config = PropertiesUtils.loadResourceFormClassPath(properties);

        this.jdbcUrl = config.get("jdbcUrl");
        this.user = config.get("user");
        this.password = config.get("password");
        String driverClass = config.get("driverClass");
        String maxPoolSize = config.get("maxPoolSize");
        String minPoolSize = config.get("minPoolSize");
        String initialPoolSize = config.get("initialPoolSize");
        String maxIdleTime = config.get("maxIdleTime");
        String acquireIncrement = config.get("acquireIncrement");

        if (StringUtils.isNotBlank(driverClass)) {
            this.setDriverClass(driverClass);
        }
        if (StringUtils.isNotBlank(maxPoolSize)) {
            this.setMaxPoolSize(toInt(maxPoolSize));
        }
        if (StringUtils.isNotBlank(minPoolSize)) {
            this.setMinPoolSize(toInt(minPoolSize));
        }
        if (StringUtils.isNotBlank(initialPoolSize)) {
            this.setInitialPoolSize(toInt(initialPoolSize));
        }
        if (StringUtils.isNotBlank(maxIdleTime)) {
            this.setMaxIdleTime(toInt(maxIdleTime));
        }
        if (StringUtils.isNotBlank(acquireIncrement)) {
            this.setAcquireIncrement(toInt(acquireIncrement));
        }
    }

    /**
     * @see com.easy.framwork.datasoruce.DatasourceProvider#getDataSource()
     */
    @Override
    public DataSource getDataSource() {
        if (dataSource == null) {
            init();
        }
        return dataSource;
    }

    /**
     * 初始化c3p0
     */
    private void init() {
        dataSource = new ComboPooledDataSource();
        dataSource.setJdbcUrl(jdbcUrl);
        dataSource.setUser(user);
        dataSource.setPassword(password);
        try {
            dataSource.setDriverClass(driverClass);
        }
        catch (PropertyVetoException e) {
            dataSource = null;
            throw new RuntimeException(e);
        }
        dataSource.setMaxPoolSize(maxPoolSize);
        dataSource.setMinPoolSize(minPoolSize);
        dataSource.setInitialPoolSize(initialPoolSize);
        dataSource.setMaxIdleTime(maxIdleTime);
        dataSource.setAcquireIncrement(acquireIncrement);
    }

    public void setDriverClass(String driverClass) {
        if (StringUtils.isBlank(driverClass)) {
            throw new IllegalArgException("driverClass can not be blank.");
        }
        this.driverClass = driverClass;
    }

    public void setMaxPoolSize(int maxPoolSize) {
        if (maxPoolSize < 1) {
            throw new IllegalArgException("maxPoolSize must more than 0.");
        }
        this.maxPoolSize = maxPoolSize;
    }

    public void setMinPoolSize(int minPoolSize) {
        if (minPoolSize < 1) {
            throw new IllegalArgException("minPoolSize must more than 0.");
        }
        this.minPoolSize = minPoolSize;
    }

    public void setInitialPoolSize(int initialPoolSize) {
        if (initialPoolSize < 1) {
            throw new IllegalArgException("initialPoolSize must more than 0.");
        }
        this.initialPoolSize = initialPoolSize;
    }

    public void setMaxIdleTime(int maxIdleTime) {
        if (maxIdleTime < 1) {
            throw new IllegalArgException("maxIdleTime must more than 0.");
        }
        this.maxIdleTime = maxIdleTime;
    }

    public void setAcquireIncrement(int acquireIncrement) {
        if (acquireIncrement < 1) {
            throw new IllegalArgException("acquireIncrement must more than 0.");
        }
        this.acquireIncrement = acquireIncrement;
    }

    /**
     * 
     * 
     * @param str
     * @return
     */
    private Integer toInt(String str) {
        return Integer.parseInt(str);
    }

}
